package com.meta.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * @Author: xieZW
 * @Date: 2021/11/25 19:48
 */
public class DateUtil {

    private static final Logger logger = LoggerFactory.getLogger(DateUtil.class);

    public static final String SPLIT_STR = "-";

    public static final String[] CHINESE_YMD_STR = {"年", "月", "日",
            "－", "、"};

    public static final String[] CHINESE_YMD_REPLACE_CHAR = {SPLIT_STR,
            SPLIT_STR, SPLIT_STR, SPLIT_STR, SPLIT_STR};

    public static final String[] ENGLISH_M_STR = {"january",
            "february", "march", "april", "may", "june", "july", "august",
            "september", "october", "november", "december", "jan.", "feb.",
            "mar.", "apr.", "jun.", "jul.", "aug.", "sep.", "oct.", "nov.",
            "dec.", "jan", "feb", "mar", "apr", "jun", "jul", "aug", "sep",
            "oct", "nov", "dec", "sept"};

    public static final String[] ENGLISH_M_REPLACE_CHAR = {"-01-", "-02-",
            "-03-", "-04-", "-05-", "-06-", "-07-", "-08-", "-09-", "-10-",
            "-11-", "-12-", "-01-", "-02-", "-03-", "-04-", "-06-", "-07-",
            "-08-", "-09-", "-10-", "-11-", "-12-", "-01-", "-02-", "-03-",
            "-04-", "-06-", "-07-", "-08-", "-09-", "-10-", "-11-", "-12-",
            "-09-"};

    // public static final String[] CHINESE_NOW_DATE = { "现在", "至今",
    // "Present", "Now", "今", "Today", "当前" };

    public static final Pattern NOW_DATE_PATTERN = Pattern
            .compile("现\\s*在|至\\s*今|当\\s*前|目\\s*前|今天?|Present|Today|Now|So[ ]Far",
                    Pattern.CASE_INSENSITIVE);

    public static final char SPLIT_CHAR = '-';

    public static final String DATE_FORMAT_DMY = "dd/MM/yyyy";

    // 默认的日期显示格式
    public static final String DATE_FORMAT_YMD = "yyyy-MM-dd";

    public static final String DATE_FORMAT_YM = "yyyy-MM";

    public static final String DATE_FORMAT_Y = "yyyy";

    public static final String DATE_FORMAT_YMDHMS = "yyyy-MM-dd HH:mm:ss";

    public static final String DATE_FORMAT_YMDHM = "yyyy-MM-dd HH:mm";

    public static final String DATE_FORMAT_MDHM = "MM-dd HH:mm";

    public static final String DATE_NUMBER_FORMAT_YMD = "yyyyMMdd";

    public static final String DATE_NUMBER_FORMAT_YMDHMS = "yyyyMMddHHmmssSS";

    public static final String DATE_NUMBER_FORMAT_YM = "yyyyMM";

    public static final String DATE_NUMBER_FORMAT_Y = "yyyy";

    public static final String DATE_FORMAT_YMD_2 = "yyyy.MM.dd HH:mm:ss";

    public static final String DATE_NUMBER_FORMAT_YMDH = "yyyyMMddHH";

    public static final String DATE_NUMBER_FORMAT_YMDHM = "yyyyMMddHHmm";

    public static final String DATE_FORMAT_YMDHMS_SS = "yyyy-MM-dd HH:mm:ss SS";

    public static final String DATE_FORMAT_YMDHMS_SS_TWO = "yyyy-MM-dd HH:mm:ss.SS";

    public static final String DATE_FORMAT_01 = "yyyy.MM.dd";


    /**
     * 获取当前时间的月份
     *
     * @return
     */
    public static Timestamp mysqlTimestamp() {
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        return timestamp;
    }

    /**
     * 获取当前时间的月份
     *
     * @return
     */
    public static Integer weekOfYear() {
        Calendar calendar = Calendar.getInstance();
        Integer week = calendar.get(Calendar.WEEK_OF_YEAR);
        return week;
    }

    /**
     * 获取当前时间的月份
     *
     * @return
     */
    public static Integer dayOfYear() {
        Calendar calendar = Calendar.getInstance();
        Integer date = calendar.get(Calendar.DAY_OF_YEAR);
        return date;
    }

    /**
     * 系统中至今代表的日期
     */
    public static final Date SO_FAR_DAY = createDate(1000,
            1, 1,
            0, 0,
            0, 0);

    // public static final String[][] DATE_FORMAT = {
    // { "(19|20)\\d{2}-\\d{2}-\\d{2}", "yyyy-MM-dd" },
    // { "(19|20)\\d{2}-\\d{2}-\\d{1}", "yy-MM-d" },
    // { "(19|20)\\d{2}-\\d{1}-\\d{2}", "yyyy-M-dd" },
    // { "(19|20)\\d{2}-\\d{1}-\\d{1}", "yyyy-M-d" },
    // { "\\d{2}-\\d{2}-\\d{2}", "yy-MM-dd" },
    // { "\\d{2}-\\d{2}-\\d{1}", "yy-MM-d" },
    // { "\\d{2}-\\d{1}-\\d{2}", "yy-M-dd" },
    // { "\\d{2}-\\d{1}-\\d{1}", "yy-M-d" } };

    public static Date getNowDate() {

        return getNowDate(DATE_FORMAT_YMD);
    }

    public static Date getNowDate(String format) {

        try {
            return charToDate(DateUtil.format(new Date(), format), format);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return null;
        }
    }

    public static int getAge(Date birthDay) {

        Calendar cal = Calendar.getInstance();

        if (cal.before(birthDay)) {
            throw new IllegalArgumentException(
                    "The birthDay is before Now.It's unbelievable!");
        }

        int yearNow = cal.get(Calendar.YEAR);
        // int monthNow = cal.get(Calendar.MONTH);
        // int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
        cal.setTime(birthDay);

        int yearBirth = cal.get(Calendar.YEAR);
        // int monthBirth = cal.get(Calendar.MONTH);
        // int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

        int age = yearNow - yearBirth;
        // ---------by hzp 2014.8.20 年龄不按天算，只按年算
        // if (monthNow <= monthBirth) {
        // if (monthNow == monthBirth) {
        // // monthNow==monthBirth
        // if (dayOfMonthNow < dayOfMonthBirth) {
        // age--;
        // } else {
        // // do nothing
        // }
        // } else {
        // // monthNow>monthBirth
        // age--;
        // }
        // } else {
        // // monthNow<monthBirth
        // // donothing
        // }
        // age += 1;
        return age;
    }

    /**
     * 解析简历内容时判读是否为日期型
     *
     * @param str
     * @return
     */
    public static boolean isDate(String str) {

        str = str.trim();

        return NOW_DATE_PATTERN.matcher(str).matches() || DATE_PATTERN_1
                .matcher(str).matches()
                || DATE_PATTERN_2.matcher(str).matches()
                || DATE_PATTERN_3.matcher(str).matches()
                || DATE_PATTERN_4.matcher(str).matches()
                || DATE_PATTERN_5.matcher(str).matches()
                || DATE_PATTERN_6.matcher(str).matches()
                || DATE_PATTERN_7.matcher(str).matches()
                || DATE_PATTERN_8.matcher(str).matches()
                || DATE_PATTERN_9.matcher(str).matches()
                || DATE_PATTERN_10.matcher(str).matches()
                || DATE_PATTERN_11.matcher(str).matches()
                || DATE_PATTERN_12.matcher(str).matches()
                || DATE_PATTERN_13.matcher(str).matches()
                || DATE_PATTERN_14.matcher(str).matches()
                || DATE_PATTERN_15.matcher(str).matches()
                || DATE_PATTERN_16.matcher(str).matches()
                || DATE_PATTERN_17.matcher(str).matches();
    }

    public static boolean isToDay(Date date) {

        String now = DateUtil.format(new Date(), DATE_FORMAT_YMD);
        String datestr = DateUtil.format(date, DATE_FORMAT_YMD);
        return now.equals(datestr);
    }


    public static final Pattern DATE_PATTERN_1 = Pattern
            .compile("(19|20)\\d{2}\\s*年?\\s*(\\p{Punct})\\s*(1[0-2]|0?[1-9])\\s*月?\\s*\\2\\s*(3[0-1]|[1-2][0-9]|0?[1-9])\\s*日?");

    public static final Pattern DATE_PATTERN_2 = Pattern
            .compile("(19|20)\\d{2}\\s*年\\s*(1[0-2]|0?[1-9])\\s*月\\s*(3[0-1]|[1-2][0-9]|0?[1-9])\\s*日?");

    public static final Pattern DATE_PATTERN_3 = Pattern
            .compile("(19|20)\\d{2}\\s*年?\\s*\\p{Punct}\\s*(1[0-2]|0?[1-9])\\s*月?");

    public static final Pattern DATE_PATTERN_4 = Pattern
            .compile("((19|20)\\d{2}\\s*年\\s*(1[0-2]|0?[1-9])\\s*月?)");

    public static final Pattern DATE_PATTERN_5 = Pattern
            .compile("(19|20)\\d{2}\\s*年?");

    public static final Pattern DATE_PATTERN_6 = Pattern
            .compile("(3[0-1]|[1-2][0-9]|0?[1-9])\\s*(\\p{Punct})\\s*(1[0-2]|0?[1-9])\\s*\\2\\s*(19|20)\\d{2}");

    public static final Pattern DATE_PATTERN_7 = Pattern
            .compile("(1[0-2]|0?[1-9])\\s*\\p{Punct}\\s*(19|20)\\d{2}");

    public static final Pattern DATE_PATTERN_8 = Pattern
            .compile("(3[0-1]|[1-2][0-9]|0?[1-9])\\s+(January|February|March|April|May|June|July|August|September|October|November|December|(Jan|Feb|Mar|Apr|Jun|Jul|Aug|Sep|Oct|Nov|Dec|Sept)\\.?)\\s+(19|20)\\d{2}");

    public static final Pattern DATE_PATTERN_9 = Pattern
            .compile("(3[0-1]|[1-2][0-9]|0?[1-9])\\s*(\\p{Punct})\\s*(January|February|March|April|May|June|July|August|September|October|November|December|(Jan|Feb|Mar|Apr|Jun|Jul|Aug|Sep|Oct|Nov|Dec|Sept)\\.?)\\s*\\2\\s*(19|20)\\d{2}");

    public static final Pattern DATE_PATTERN_10 = Pattern
            .compile("(January|February|March|April|May|June|July|August|September|October|November|December|(Jan|Feb|Mar|Apr|Jun|Jul|Aug|Sep|Oct|Nov|Dec|Sept)\\.?)\\s+([Oo][Ff]\\s+)?(19|20)\\d{2}");

    public static final Pattern DATE_PATTERN_11 = Pattern
            .compile("(January|February|March|April|May|June|July|August|September|October|November|December|(Jan|Feb|Mar|Apr|Jun|Jul|Aug|Sep|Oct|Nov|Dec|Sept)\\.?)\\s*\\p{Punct}\\s*(19|20)\\d{2}");

    public static final Pattern DATE_PATTERN_12 = Pattern
            .compile("(\\d{2})\\s*\\p{Punct}\\s*(1[0-2]|0?[1-9])");

    public static final Pattern DATE_PATTERN_13 = Pattern
            .compile("(19|20)\\d{2}\\s*年?\\s*(\\p{Punct})\\s*(1[0-2]|0?[1-9])\\s*月?\\s*\\2\\s*(3[0-1]|[1-2][0-9]|0?[1-9])\\s*日?\\s+\\d{2}\\p{Punct}\\d{2}");

    public static final Pattern DATE_PATTERN_14 = Pattern
            .compile("(19|20)\\d{2}\\s*年?\\s*(\\p{Punct})\\s*(1[0-2]|0?[1-9])\\s*月?\\s*\\2\\s*(3[0-1]|[1-2][0-9]|0?[1-9])\\s*日?\\s+\\d{2}\\p{Punct}\\d{2}\\p{Punct}\\d{2}");

    public static final Pattern DATE_PATTERN_15 = Pattern
            .compile("(19|20)\\d{2}\\s*年?\\s*(\\p{Punct})\\s*(1[0-2]|0?[1-9])\\s*月?\\s*\\2\\s*(3[0-1]|[1-2][0-9]|0?[1-9])\\s*日?\\s+\\d{2}\\p{Punct}\\d{2}\\p{Punct}\\d{2}\\p{Punct}\\d{1}");

    public static final Pattern DATE_PATTERN_16 = Pattern
            .compile("(19|20)\\d{2}(1[0-2]|0?[1-9])");

    public static final Pattern DATE_PATTERN_17 = Pattern
            .compile("(19|20)\\d{2}(1[0-2]|0?[1-9])(3[0-1]|[1-2][0-9]|0?[1-9])");

    public static final String Punct = "\\p{Punct}{1,}|[Oo][Ff]";


    public static boolean isFullDate(String str) {

        if (StringUtils.isEmpty(str)) {
            return false;
        }

        if (NOW_DATE_PATTERN.matcher(str).matches()) {
            return false;
        }

        str = str.trim();
        return DATE_PATTERN_1.matcher(str).matches() || DATE_PATTERN_2
                .matcher(str).matches()
                || DATE_PATTERN_6.matcher(str).matches()
                || DATE_PATTERN_8.matcher(str).matches()
                || DATE_PATTERN_9.matcher(str).matches()
                || DATE_PATTERN_17.matcher(str).matches();
    }


    public static Date parseXlsDate(String str) throws Exception {

        if (StringUtils.isEmpty(str)) {
            return null;
        }

        str = str.replaceAll(Punct, SPLIT_STR);

        DateFormat format = null;
        if (DATE_PATTERN_14.matcher(str).matches()) {

            format = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
        } else if (DATE_PATTERN_13.matcher(str).matches()) {

            format = new SimpleDateFormat("yyyy-MM-dd HH-mm");
        } else if (DATE_PATTERN_1.matcher(str).matches() || DATE_PATTERN_2
                .matcher(str).matches()) {

            format = new SimpleDateFormat(DATE_FORMAT_YMD);
        } else if (DATE_PATTERN_3.matcher(str).matches() || DATE_PATTERN_4
                .matcher(str).matches()) {

            format = new SimpleDateFormat(DATE_FORMAT_YM);
        } else if (DATE_PATTERN_5.matcher(str).matches()) {

            format = new SimpleDateFormat(DATE_FORMAT_Y);
        } else if (DATE_PATTERN_6.matcher(str).matches()) {

            format = new SimpleDateFormat("dd-MM-yyyy");
        } else if (DATE_PATTERN_7.matcher(str).matches()) {

            format = new SimpleDateFormat("MM-yyyy");
        } else if (DATE_PATTERN_8.matcher(str).matches()) {

            format = new SimpleDateFormat("dd MM yyyy");
        } else if (DATE_PATTERN_9.matcher(str).matches()) {

            format = new SimpleDateFormat("dd-MM-yyyy");
        } else if (DATE_PATTERN_10.matcher(str).matches()) {

            format = new SimpleDateFormat("MM yyyy");
        } else if (DATE_PATTERN_11.matcher(str).matches()) {

            format = new SimpleDateFormat("MM-yyyy");
        } else if (DATE_PATTERN_12.matcher(str).matches()) {

            format = new SimpleDateFormat("yy-MM");
        } else if (DATE_PATTERN_16.matcher(str).matches()) {
            format = new SimpleDateFormat(DATE_NUMBER_FORMAT_YM);
        } else if (DATE_PATTERN_17.matcher(str).matches()) {
            format = new SimpleDateFormat(DATE_NUMBER_FORMAT_YMD);
        }

        return format != null ? format.parse(str) : null;
    }

    public static Date charToDate(String dateStr, String format)
            throws Exception {

        Date dasql = null;
        if (StringUtils.isEmpty(dateStr)) {
            return dasql;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        dasql = sdf.parse(dateStr);

        return dasql;
    }

    // 获取转换过来的字符串

    public static String dateToChar(Date dateIn, String format) {

        if (dateIn == null || format == null) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.CHINA);
        String dateStr = sdf.format(dateIn);
        return dateStr;
    }

    private static String cleanup(String str) {

        if (StringUtils.isEmpty(str)) {
            return str;
        }
        int sz = str.length();
        char chs[] = new char[sz];
        int count = 0;
        for (int i = 0; i < sz; i++) {

            if (Character.isDigit(str.charAt(i))) {

                chs[count++] = str.charAt(i);
            } else if (str.charAt(i) == DateUtil.SPLIT_CHAR) {

                chs[count++] = str.charAt(i);
            }
        }

        int end = count - 1;
        if (end > 0 && chs[end] == DateUtil.SPLIT_CHAR) {

            count--;
        }

        if (count != sz) {
            str = new String(chs, 0, count);
        }

        while (str.startsWith(DateUtil.SPLIT_STR)) {
            str = str.substring(DateUtil.SPLIT_STR.length());
        }
        while (str.endsWith(DateUtil.SPLIT_STR)) {
            str = str.substring(0,
                    (str.length() - DateUtil.SPLIT_STR.length()));
        }

        return str;
    }

    public static String format(Date date) {

        if (date == null) {
            return null;
        }
        SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT_YMD);
        return format.format(date);
    }

    public static String formatYMDHMS(Date date) {

        if (date == null) {
            return null;
        }
        SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT_YMDHMS);
        return format.format(date);
    }

    public static String formatYMDHM(Date date) {

        if (date == null) {
            return null;
        }
        SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT_YMDHM);
        return format.format(date);
    }

    public static String format(Date date, String patten) {

        if (date == null) {
            return null;
        }
        if (StringUtils.isEmpty(patten)) {
            patten = DATE_FORMAT_YMD;
        }
        SimpleDateFormat format = new SimpleDateFormat(patten);
        return format.format(date);
    }

    public static int getDayBetweenTwoDate(Date sDate, Date bDate) {

        if (sDate != null && bDate != null) {
            long sTime = sDate.getTime();
            long bTime = bDate.getTime();
            long l = bTime - sTime;
            int day = (int) (l / (1000 * 3600 * 24));

            return day;
        }
        return 0;
    }

    public static int getDaysBetweenTwoDateWithoutHour(Date sDate, Date bDate) {

        if (sDate != null && bDate != null) {
            Date beginDate = new Date(sDate.getTime());
            beginDate.setHours(0);
            beginDate.setMinutes(0);
            beginDate.setSeconds(0);

            Date endDate = new Date(bDate.getTime());
            endDate.setHours(0);
            endDate.setMinutes(0);
            endDate.setSeconds(0);

            long sTime = beginDate.getTime();
            long bTime = endDate.getTime();
            long l = bTime - sTime;
            int day = (int) (l / (1000 * 3600 * 24));

            return day + 1;
        }
        return 0;
    }

    public static int getHoursBetweenTwoDate(Date sDate, Date bDate) {

        if (sDate != null && bDate != null) {
            long sTime = sDate.getTime();
            long bTime = bDate.getTime();
            long l = bTime - sTime;
            int day = (int) (l / (1000 * 3600));

            return day;
        }
        return 0;
    }


    public static int getMinutes(Date sDate, Date bDate) {

        if (sDate != null && bDate != null) {
            long sTime = sDate.getTime();
            long bTime = bDate.getTime();
            long l = bTime - sTime;
            int minute = (int) (l / (1000 * 60));

            return minute;
        }
        return 0;
    }

    public static int getSecondBetweenTwoDate(Date sDate, Date bDate) {

        if (sDate != null && bDate != null) {
            long sTime = sDate.getTime();
            long bTime = bDate.getTime();
            long l = bTime - sTime;
            int day = (int) (l / (1000));

            return day;
        }
        return 0;
    }

    /**
     * 得到二个日期间的间隔天数
     */

    private static final String EEEE = "EEEE";

    /**
     * 根据一个日期，返回是星期几的字符串
     *
     * @param dateStr
     * @param locale
     * @return
     */
    public static String getWeek(String dateStr, Locale locale) {

        // 再转换为时间
        Date date = strToDate(dateStr);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        // int hour=c.get(Calendar.DAY_OF_WEEK);
        // hour中存的就是星期几了，其范围 1~7
        // 1=星期日 7=星期六，其他类推
        return new SimpleDateFormat(EEEE, locale).format(c
                .getTime());
    }

    /**
     * 根据一个日期，返回是星期几的字符串
     *
     * @param date
     * @param locale
     * @return
     */
    public static String getWeek(Date date, Locale locale) {

        // 再转换为时间
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        // int hour=c.get(Calendar.DAY_OF_WEEK);
        // hour中存的就是星期几了，其范围 1~7
        // 1=星期日 7=星期六，其他类推
        return new SimpleDateFormat(EEEE, locale).format(c
                .getTime());
    }

    /**
     * 将短时间格式字符串转换为时间 yyyy-MM-dd
     *
     * @param strDate
     * @return
     */
    public static Date strToDate(String strDate) {

        if (StringUtils.isEmpty(strDate)) {
            return null;
        }
        SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT_YMD);
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(strDate, pos);
        return strtodate;
    }

    /**
     * 两个时间之间的天数
     *
     * @param date1
     * @param date2
     * @return
     */
    public static long getDays(String date1, String date2) {

        if (StringUtils.isEmpty(date1)) {
            return 0;
        }
        if (StringUtils.isEmpty(date2)) {
            return 0;
        }
        // 转换为标准时间
        SimpleDateFormat myFormatter = new SimpleDateFormat(DATE_FORMAT_YMD);
        Date date = null;
        Date mydate = null;
        try {
            date = myFormatter.parse(date1);
            mydate = myFormatter.parse(date2);
        } catch (Exception e) {
        }
        long day = (date.getTime() - mydate.getTime()) / (24 * 60 * 60 * 1000);
        return day;
    }

    public static int getMonths(Date date1, Date date2) {

        int iMonth = 0;
        int flag = 0;
        try {
            Calendar objCalendarDate1 = Calendar.getInstance();
            objCalendarDate1.setTime(date1);

            Calendar objCalendarDate2 = Calendar.getInstance();
            objCalendarDate2.setTime(date2);

            if (objCalendarDate2.equals(objCalendarDate1)) {
                return 0;
            }
            if (objCalendarDate1.after(objCalendarDate2)) {
                Calendar temp = objCalendarDate1;
                objCalendarDate1 = objCalendarDate2;
                objCalendarDate2 = temp;
            }
            if (objCalendarDate2.get(Calendar.DAY_OF_MONTH) < objCalendarDate1
                    .get(Calendar.DAY_OF_MONTH)) {
                flag = 1;
            }

            if (objCalendarDate2.get(Calendar.YEAR) > objCalendarDate1
                    .get(Calendar.YEAR)) {
                iMonth = ((objCalendarDate2.get(Calendar.YEAR) - objCalendarDate1
                        .get(Calendar.YEAR)) * 12
                        + objCalendarDate2.get(Calendar.MONTH) - flag) - objCalendarDate1
                        .get(Calendar.MONTH);
            } else {
                iMonth = objCalendarDate2.get(Calendar.MONTH) - objCalendarDate1
                        .get(Calendar.MONTH) - flag;
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return iMonth;
    }

    // 计算当月最后一天,返回字符串

    public static Date getLastDayOfMonth() {

        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.DATE, 1);// 设为当前月的1号
        lastDate.add(Calendar.MONTH, 1);// 加一个月，变为下月的1号
        lastDate.add(Calendar.DATE, -1);// 减去一天，变为当月最后一天
        lastDate.set(Calendar.HOUR_OF_DAY, 0);
        lastDate.set(Calendar.MINUTE, 0);
        lastDate.set(Calendar.SECOND, 0);
        lastDate.set(Calendar.MILLISECOND, 0);
        return lastDate.getTime();
    }

    // 计算当月最后一天,返回字符串
    public static String getLastDayOfMonthStr() {

        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_YMD);

        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.DATE, 1);// 设为当前月的1号
        lastDate.add(Calendar.MONTH, 1);// 加一个月，变为下月的1号
        lastDate.add(Calendar.DATE, -1);// 减去一天，变为当月最后一天

        String str = sdf.format(lastDate.getTime());
        return str;
    }

    // 获取当月第一天
    public static String getFirstDayOfMonth() {

        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_YMD);

        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.DATE, 1);// 设为当前月的1号
        String str = sdf.format(lastDate.getTime());
        return str;
    }

    // 计算当月最后一天,返回字符串
    public static String getLastDayOfLastMonthStr() {

        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_YMD);

        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.DATE, 1);// 设为当前月的1号
        lastDate.add(Calendar.DATE, -1);// 减去一天，变为当月最后一天

        String str = sdf.format(lastDate.getTime());
        return str;
    }

    // 获取当月第一天
    public static String getFirstDayOfLastMonth() {

        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_YMD);

        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.DATE, 1);// 设为当前月的1号
        lastDate.add(Calendar.MONTH, -1);// 加一个月，变为下月的1号
        String str = sdf.format(lastDate.getTime());
        return str;
    }

    // 获取当月第一天
    public static Date getFirstDateOfMonth() {

        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.DATE, 1);// 设为当前月的1号
        lastDate.set(Calendar.HOUR_OF_DAY, 0);
        lastDate.set(Calendar.MINUTE, 0);
        lastDate.set(Calendar.SECOND, 0);
        lastDate.set(Calendar.MILLISECOND, 0);
        return lastDate.getTime();
    }

    // 获取当年的第一天
    public static Date getFirstDateOfYear() {

        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.DAY_OF_YEAR, 1);
        lastDate.set(Calendar.MONTH, 0);
        lastDate.set(Calendar.HOUR_OF_DAY, 0);
        lastDate.set(Calendar.MINUTE, 0);
        lastDate.set(Calendar.SECOND, 0);
        lastDate.set(Calendar.MILLISECOND, 0);
        return lastDate.getTime();
    }

    public static Date getFirstDateOfYear(int year) {

        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.YEAR, year);
        lastDate.set(Calendar.MONTH, 0);
        lastDate.set(Calendar.DAY_OF_MONTH, 1);
        lastDate.set(Calendar.HOUR_OF_DAY, 0);
        lastDate.set(Calendar.MINUTE, 0);
        lastDate.set(Calendar.SECOND, 0);
        lastDate.set(Calendar.MILLISECOND, 0);
        return lastDate.getTime();
    }

    public static Date getEndDateOfYear(int year) {

        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.YEAR, year);
        lastDate.set(Calendar.MONTH, 11);
        lastDate.set(Calendar.DAY_OF_MONTH, 31);
        lastDate.set(Calendar.HOUR_OF_DAY, 23);
        lastDate.set(Calendar.MINUTE, 59);
        lastDate.set(Calendar.SECOND, 59);
        return lastDate.getTime();
    }

    public static Date getFirstDateOfMonth(int year, int month) {

        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.YEAR, year);
        month = month - 1;
        lastDate.set(Calendar.MONTH, month);
        lastDate.set(Calendar.DAY_OF_MONTH, 1);
        lastDate.set(Calendar.HOUR_OF_DAY, 0);
        lastDate.set(Calendar.MINUTE, 0);
        lastDate.set(Calendar.SECOND, 0);
        lastDate.set(Calendar.MILLISECOND, 0);
        return lastDate.getTime();
    }

    public static Date getEndDateOfMonth(int year, int month) {

        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.YEAR, year);
//        month = month - 1;
        lastDate.set(Calendar.MONTH, month);
        lastDate.set(Calendar.DAY_OF_MONTH, 0);
        lastDate.set(Calendar.HOUR_OF_DAY, 23);
        lastDate.set(Calendar.MINUTE, 59);
        lastDate.set(Calendar.SECOND, 59);
        return lastDate.getTime();
    }

    public static Date getFirstDateOfQuarter(int year, int quarter) {

        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.YEAR, year);
        int firstMonth = 0;
        if (quarter == 1) {
            firstMonth = 1;
        } else if (quarter == 2) {
            firstMonth = 4;
        } else if (quarter == 3) {
            firstMonth = 7;
        } else if (quarter == 4) {
            firstMonth = 10;
        }
        firstMonth = firstMonth - 1;
        lastDate.set(Calendar.YEAR, year);
        lastDate.set(Calendar.MONTH, firstMonth);
        lastDate.set(Calendar.DAY_OF_MONTH, 1);
        lastDate.set(Calendar.HOUR_OF_DAY, 0);
        lastDate.set(Calendar.MINUTE, 0);
        lastDate.set(Calendar.SECOND, 0);
        lastDate.set(Calendar.MILLISECOND, 0);
        return lastDate.getTime();
    }

    public static Date getEndDateOfQuarter(int year, int quarter) {

        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.YEAR, year);
        int firstMonth = 0;
        if (quarter == 1) {
            firstMonth = 3;
        } else if (quarter == 2) {
            firstMonth = 6;
        } else if (quarter == 3) {
            firstMonth = 9;
        } else if (quarter == 4) {
            firstMonth = 12;
        }
//        firstMonth = firstMonth - 1;
        lastDate.set(Calendar.YEAR, year);
        lastDate.set(Calendar.MONTH, firstMonth);
        lastDate.set(Calendar.DAY_OF_MONTH, 0);
        lastDate.set(Calendar.HOUR_OF_DAY, 23);
        lastDate.set(Calendar.MINUTE, 59);
        lastDate.set(Calendar.SECOND, 59);
        return lastDate.getTime();
    }

    // 获得当前日期与本周日相差的天数
    private static int getMondayPlus() {

        Calendar cd = Calendar.getInstance();
        // 获得今天是一周的第几天，星期日是第一天，星期二是第二天......
        int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK) - 1; // 因为按中国礼拜一作为第一天所以这里减1
        if (dayOfWeek == 1) {
            return 0;
        } else {
            return 1 - dayOfWeek;
        }
    }

    // 获得本周一的日期
    public static String getMondayOfWeek() {

        int mondayPlus = getMondayPlus();
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus);
        Date monday = currentDate.getTime();

        DateFormat df = DateFormat.getDateInstance();
        String preMonday = df.format(monday);
        return preMonday;
    }

    // 获得本周星期日的日期
    public static String getCurrentWeekDay() {

        int mondayPlus = getMondayPlus();
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus + 6);
        Date monday = currentDate.getTime();

        DateFormat df = DateFormat.getDateInstance();
        String preMonday = df.format(monday);
        return preMonday;
    }

    public static boolean isPassNow(Date startDate, Integer month) {

        Calendar cal = Calendar.getInstance();
        cal.setTime(startDate);
        cal.add(Calendar.MONTH, month);
        return cal.getTime().compareTo(new Date()) >= 0 ? true : false;

    }

    /**
     * 得到几天前的时间
     *
     * @param d
     * @param day
     * @return
     */
    public static Date getDateBefore(Date d, int day) {

        Calendar now = Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.DATE, now.get(Calendar.DATE) - day);
        return now.getTime();
    }

    public static Date getDateBeforeMinute(Date d, int minute) {

        Calendar now = Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.MINUTE, now.get(Calendar.MINUTE) - minute);
        return now.getTime();
    }

    public static Date getDateBeforeYear(Date d, int year) {

        Calendar now = Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.YEAR, now.get(Calendar.YEAR) - year);
        return now.getTime();
    }

    public static Date getDateAfterYear(Date d, int year) {

        Calendar now = Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.YEAR, now.get(Calendar.YEAR) + year);
        return now.getTime();
    }

    public static Date getDateBeforeMonth(Date d, int month) {

        Calendar now = Calendar.getInstance();
        now.setTime(d);
        now.add(Calendar.MONTH, -month);
        return now.getTime();
    }

    public static Date getDateAfterMonth(Date d, int month) {

        Calendar now = Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.MONTH, now.get(Calendar.MONTH) + month);
        return now.getTime();
    }

    /**
     * 得到几天后的时间
     *
     * @param d
     * @param day
     * @return
     */
    public static Date getDateAfter(Date d, int day) {

        Calendar now = Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.DATE, now.get(Calendar.DATE) + day);
        return now.getTime();
    }

    public static Date getDateAfterHour(Date d, int hour) {

        Calendar now = Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.HOUR, now.get(Calendar.HOUR) + hour);
        return now.getTime();
    }

    public static Date getDateAfterMinute(Date d, int minute) {

        Calendar now = Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.MINUTE, now.get(Calendar.MINUTE) + minute);
        return now.getTime();
    }

    public static final String DATE_FORMAT_REPLY_MESSAGE_YMDHMS_DIAGONAL = "yyyy/M/d HH:mm:ss"; // 短信回复日期格式

    // 获取当年的第一天
    public static Date getFirstDateOfCurrentYear() {

        Calendar c = Calendar.getInstance();
        c.set(Calendar.MONTH, 0);
        int days = c.getActualMinimum(Calendar.DAY_OF_MONTH);
        c.set(Calendar.DAY_OF_MONTH, days);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    public static String getFirstDateOfCurrentYearStr() {

        return format(getFirstDateOfCurrentYear(), DATE_FORMAT_YMD);
    }

    // 获取当年的最后一天
    public static Date getLastDateOfCurrentYear() {

        Calendar c = Calendar.getInstance();
        c.set(Calendar.MONTH, 11);
        int days = c.getActualMaximum(Calendar.DAY_OF_MONTH);
        c.set(Calendar.DAY_OF_MONTH, days);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    public static String getLastDateOfCurrentYearStr() {

        return format(getLastDateOfCurrentYear(), DATE_FORMAT_YMD);
    }

    public static Date getFirstDateOfCurrentQuarter() {

        Calendar c = Calendar.getInstance();
        int month = c.get(Calendar.MONTH);

        if (month >= 0 && month <= 2) {
            c.set(Calendar.MONTH, 0);
        } else if (month >= 3 && month <= 5) {
            c.set(Calendar.MONTH, 3);
        } else if (month >= 6 && month <= 8) {
            c.set(Calendar.MONTH, 6);
        } else if (month >= 9 && month <= 11) {
            c.set(Calendar.MONTH, 9);
        }
        int days = c.getActualMinimum(Calendar.DAY_OF_MONTH);

        c.set(Calendar.DAY_OF_MONTH, days);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    public static String getFirstDateOfCurrentQuarterStr() {

        return format(getFirstDateOfCurrentQuarter(), DATE_FORMAT_YMD);
    }

    public static Date getEndDateOfCurrentQuarter() {

        Calendar c = Calendar.getInstance();
        int month = c.get(Calendar.MONTH);

        if (month >= 0 && month <= 2) {
            c.set(Calendar.MONTH, 2);
        } else if (month >= 3 && month <= 5) {
            c.set(Calendar.MONTH, 5);
        } else if (month >= 6 && month <= 8) {
            c.set(Calendar.MONTH, 8);
        } else if (month >= 9 && month <= 11) {
            c.set(Calendar.MONTH, 11);
        }
        int days = c.getActualMaximum(Calendar.DAY_OF_MONTH);

        c.set(Calendar.DAY_OF_MONTH, days);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    public static String getEndDateOfCurrentQuarterStr() {

        return format(getEndDateOfCurrentQuarter(), DATE_FORMAT_YMD);
    }

    /**
     * 得到本月最后一天
     *
     * @return
     */
    public static Date getLastDateOfMonth() {

        Calendar c = Calendar.getInstance();

        int days = c.getActualMaximum(Calendar.DAY_OF_MONTH);
        c.set(Calendar.DAY_OF_MONTH, days);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    public static String getLastDateOfMonthStr() {

        return format(getLastDateOfMonth(), DATE_FORMAT_YMD);
    }

    /**
     * 得到本月第一天
     *
     * @return
     */
    public static Date getFristDateOfMonth() {

        Calendar c = Calendar.getInstance();
        int days = c.getActualMinimum(Calendar.DAY_OF_MONTH);
        c.set(Calendar.DAY_OF_MONTH, days);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    // 得到上个月最后一天
    public static String getLastDateOfLastMonth() {

        Calendar c = Calendar.getInstance();

        int days = c.getActualMaximum(Calendar.DAY_OF_MONTH);
        c.set(Calendar.DAY_OF_MONTH, days - 1);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return format(c.getTime(), DATE_FORMAT_YMD);
    }

    // 得到上个月第一天
    public static String getFristDateOfLastMonth() {

        Calendar c = Calendar.getInstance();
        int days = c.getActualMinimum(Calendar.DAY_OF_MONTH);
        c.set(Calendar.DAY_OF_MONTH, days - 1);
        c.set(Calendar.DAY_OF_MONTH, 1);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return format(c.getTime(), DATE_FORMAT_YMD);
    }

    public static String getFristDateOfMonthStr() {

        return format(getFristDateOfMonth(), DATE_FORMAT_YMD);
    }

    // 获得本周一的日期
    public static Date getMondayOfThisWeek() {

        Calendar c = Calendar.getInstance();

        int dayofweek = c.get(Calendar.DAY_OF_WEEK) - 1;
        if (dayofweek == 0) {
            dayofweek = 7;
        }
        c.add(Calendar.DATE, -dayofweek + 1);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    // 获得上周六的日期
    public static Date getSaturdayOfLastWeek() {

        Calendar c = Calendar.getInstance();

        int dayofweek = c.get(Calendar.DAY_OF_WEEK) - 1;
        if (dayofweek == 0) {
            dayofweek = 7;
        }
        c.add(Calendar.DATE, -dayofweek - 1);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    public static String getMondayOfThisWeekStr() {

        return format(getMondayOfThisWeek(), DATE_FORMAT_YMD);
    }

    // 获得本周星期日的日期
    public static Date getSundayOfThisWeek() {

        Calendar c = Calendar.getInstance();

        int dayofweek = c.get(Calendar.DAY_OF_WEEK) - 1;
        if (dayofweek == 0) {
            dayofweek = 7;
        }
        c.add(Calendar.DATE, -dayofweek + 7);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    // 获得本周星期五的日期
    public static Date getFridayOfThisWeek() {

        Calendar c = Calendar.getInstance();

        int dayofweek = c.get(Calendar.DAY_OF_WEEK) - 1;
        if (dayofweek == 0) {
            dayofweek = 7;
        }
        c.add(Calendar.DATE, -dayofweek + 5);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    public static String getSundayOfThisWeekStr() {

        return format(getSundayOfThisWeek(), DATE_FORMAT_YMD);
    }

    /**
     * ｛formatHMS格式为 yyyy-MM-dd 00:00:00｝
     *
     * @param inDate
     * @param formatHMS
     * @return
     * @author
     * @zuo_xz
     * @created 2013-9-4 下午03:57:49
     * @lastModified
     * @history
     */
    public static Date getFormatHMSDate(Date inDate, String formatHMS) {

        if (formatHMS != null) {
            String strHMS = formatHMS.trim().replaceAll("/", "-");
            String ss = format(inDate, strHMS);
            try {
                Date outDate = new SimpleDateFormat(DATE_FORMAT_YMDHMS)
                        .parse(ss);
                return outDate;
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                return null;
            }
        }
        return null;
    }

    /**
     * 根据输入的年龄，得到出生年 add by lchang
     */
    public static Integer getBirthDay(int age) {

        Calendar cal = Calendar.getInstance();
        int yearNow = cal.get(Calendar.YEAR);
        Integer birthDayInt = yearNow - age + 1;
        return birthDayInt;
    }

    public static String getMaxBirthday(int age) {

        String beginDate = null;
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.YEAR, -age);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);

        beginDate = DateUtil.format(cal.getTime());

        return beginDate;
    }

    public static String getMinBirthday(int age) {

        String endDate = null;
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.YEAR, -(age - 1));
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        endDate = DateUtil.format(cal.getTime());
        return endDate;

    }

//    private static final String TIMESHOW_MINUTES             = "RESUME_SCORE_TIMESHOW_MINUTES";
//
//    private static final String TIMESHOW_HOURS               = "RESUME_SCORE_TIMESHOW_HOURS";
//
//    private static final String RESUME_SCORE_TIMESHOW_SECOND = "RESUME_SCORE_TIMESHOW_SECOND";
//
//    public static String getTimeShow(Date addDate) {
//
//        if (addDate == null) {
//            return "";
//        } else {
//            Calendar addCalendar = Calendar.getInstance();
//            addCalendar.setTime(addDate);
//            Calendar now = Calendar.getInstance();
//            if (addCalendar.compareTo(now) == 1) {
//                return "";
//            }
//            if (addCalendar.get(Calendar.ERA) == now.get(Calendar.ERA) && addCalendar
//                    .get(Calendar.YEAR) == now.get(Calendar.YEAR)) {
//                if (!(addCalendar.get(Calendar.DAY_OF_YEAR) == now
//                        .get(Calendar.DAY_OF_YEAR))) {
//                    return format(addDate, DATE_FORMAT_MDHM);
//                } else if (!(addCalendar.get(Calendar.HOUR_OF_DAY) == now
//                        .get(Calendar.HOUR_OF_DAY))) {
//                    Object[] args = new Object[1];
//                    args[0] = now.get(Calendar.HOUR_OF_DAY) - addCalendar
//                            .get(Calendar.HOUR_OF_DAY);
//                    return Messages.getMessage(TIMESHOW_HOURS, args);
//                } else if (!(addCalendar.get(Calendar.MINUTE) == now
//                        .get(Calendar.MINUTE))) {
//                    Object[] args = new Object[1];
//                    args[0] = now.get(Calendar.MINUTE) - addCalendar
//                            .get(Calendar.MINUTE);
//                    return Messages.getMessage(TIMESHOW_MINUTES, args);
//                } else {
//                    return Messages.getMessage(RESUME_SCORE_TIMESHOW_SECOND);
//                }
//            } else {
//                return format(addDate, DATE_FORMAT_YMDHM);
//            }
//        }
//    }

    public static Date createDate(int year,
                                  int month,
                                  int date,
                                  int hour,
                                  int minute,
                                  int second,
                                  int millisecond) {

        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, date, hour, minute, second);
        calendar.set(Calendar.MILLISECOND, millisecond);
        return calendar.getTime();
    }

    // joda-time优化start

    /**
     * @param year
     * @param month
     * @param date
     * @return
     */
    @Deprecated
    public static Date createDate(int year, int month, int date) {

        return createDate(year, month, date, 0, 0, 0, 0);
    }

    /**
     * 获取所给日期前几天或后 几天
     *
     * @param date
     * @param offsetDay 正为后，负为前。
     * @return
     * @deprecated 使用DateTime.plusDays(int).toDate()和DateTime.plusDays.miniusDays
     * (int).toDate()替代
     */
    @Deprecated
    public static Date getDayOffset(Date date, int offsetDay) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + offsetDay);
        return calendar.getTime();
    }

    /**
     * 获取今天0时0分0秒的Date对象
     *
     * @deprecated 使用DateTime.now().withTimeAtStartOfDay().toDate()替代
     * @return
     */

    /**
     * 获取明天0时0分0秒的Date对象
     *
     * @return
     * @deprecated 使用DateTime.now().withTimeAtStartOfDay().plusDays(1).toDate()替代
     */

    // joda-time优化end
    public static void main(String[] args) {

        Date date = new Date();
        // int day =DateUtil.getDayOfWeek(date);
        // int monthday = DateUtil.getDayOfMonth(date);
        System.out.println(date);
        System.out.println(DateUtil.getDayOffset(date, 3));
        System.out.println(DateUtil.getHoursBetweenTwoDate(date, DateUtil
                .getDayOffset(date, 3)));
        // System.out.println("day:"+day+"\t"+"dayofMonth:"+monthday);
    }

    private static int getMondayDate(Date beginDate) {

        Calendar cd = Calendar.getInstance();
        // 获得今天是一周的第几天，星期日是第一天，星期二是第二天......
        cd.setTime(beginDate);
        int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK) - 1; // 因为按中国礼拜一作为第一天所以这里减1
        if (dayOfWeek == 1) {
            return 0;
        } else {
            return 1 - dayOfWeek;
        }
    }

    /**
     * 获得星期几
     *
     * @param date
     * @return
     */
    public static int getDayOfWeek(Date date) {

        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK) - 2;
        if (dayOfWeek == -1) {
            dayOfWeek = 6;
        }
        return dayOfWeek;
    }

    public static int getDayOfMonth(Date date) {

        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        int dayOfMonth = cd.get(Calendar.DAY_OF_MONTH);
        return dayOfMonth;
    }

    public static int getYear(Date date) {

        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        int year = cd.get(Calendar.YEAR);
        return year;
    }

    public static Date getMondayOfWeek(Date beginDate) {

        int mondayPlus = 0;
        if (beginDate != null) {
            mondayPlus = getMondayDate(beginDate);
        } else {
            mondayPlus = getMondayPlus();
        }
        GregorianCalendar currentDate = new GregorianCalendar();
        if (beginDate != null) {
            currentDate.setTime(beginDate);
        }
        currentDate.add(GregorianCalendar.DATE, mondayPlus);
        Date monday = currentDate.getTime();

        return monday;
    }

    public static String getMondayOfLastWeek(Date beginDate) {

        int mondayPlus = 0;
        if (beginDate != null) {
            mondayPlus = getMondayDate(beginDate);
        } else {
            mondayPlus = getMondayPlus();
        }
        GregorianCalendar currentDate = new GregorianCalendar();
        if (beginDate != null) {
            currentDate.setTime(beginDate);
        }
        currentDate.add(GregorianCalendar.DATE, mondayPlus - 7);
        Date monday = currentDate.getTime();

        DateFormat df = DateFormat.getDateInstance();
        String preMonday = df.format(monday);
        return preMonday;
    }

    public static Date getMondayDateOfLastWeek(Date beginDate) {

        int mondayPlus = 0;
        if (beginDate != null) {
            mondayPlus = getMondayDate(beginDate);
        } else {
            mondayPlus = getMondayPlus();
        }
        GregorianCalendar currentDate = new GregorianCalendar();
        if (beginDate != null) {
            currentDate.setTime(beginDate);
        }
        currentDate.add(GregorianCalendar.DATE, mondayPlus - 7);
        Date monday = currentDate.getTime();
        return monday;
    }

    public static String getMondayOfLastFourWeek(Date beginDate) {

        int mondayPlus = 0;
        if (beginDate != null) {
            mondayPlus = getMondayDate(beginDate);
        } else {
            mondayPlus = getMondayPlus();
        }
        GregorianCalendar currentDate = new GregorianCalendar();
        if (beginDate != null) {
            currentDate.setTime(beginDate);
        }
        currentDate.add(GregorianCalendar.DATE, mondayPlus - 14);
        Date monday = currentDate.getTime();

        DateFormat df = DateFormat.getDateInstance();
        String preMonday = df.format(monday);
        return preMonday;
    }

    public static Date getMondayOfLastFourWeekDate(Date beginDate) {

        int mondayPlus = 0;
        if (beginDate != null) {
            mondayPlus = getMondayDate(beginDate);
        } else {
            mondayPlus = getMondayPlus();
        }
        GregorianCalendar currentDate = new GregorianCalendar();
        if (beginDate != null) {
            currentDate.setTime(beginDate);
        }
        currentDate.add(GregorianCalendar.DATE, mondayPlus - 35);
        Date monday = currentDate.getTime();

        return monday;
    }

    public static String getSundayOfLastWeek(Date endDate) {

        int mondayPlus = 0;
        if (endDate != null) {
            mondayPlus = getMondayDate(endDate);
        } else {
            mondayPlus = getMondayPlus();
        }
        GregorianCalendar currentDate = new GregorianCalendar();
        if (endDate != null) {
            currentDate.setTime(endDate);
        }
        currentDate.add(GregorianCalendar.DATE, mondayPlus - 1);
        Date monday = currentDate.getTime();

        DateFormat df = DateFormat.getDateInstance();
        String preMonday = df.format(monday);
        return preMonday;
    }

    public static Date getSundayDateOfLastWeek(Date endDate) {

        int mondayPlus = 0;
        if (endDate != null) {
            mondayPlus = getMondayDate(endDate);
        } else {
            mondayPlus = getMondayPlus();
        }
        GregorianCalendar currentDate = new GregorianCalendar();
        if (endDate != null) {
            currentDate.setTime(endDate);
        }
        currentDate.add(GregorianCalendar.DATE, mondayPlus - 1);
        Date monday = currentDate.getTime();

        return monday;
    }

    public static String getSundayOfLastFourWeek(Date endDate) {

        int mondayPlus = 0;
        if (endDate != null) {
            mondayPlus = getMondayDate(endDate);
        } else {
            mondayPlus = getMondayPlus();
        }
        GregorianCalendar currentDate = new GregorianCalendar();
        if (endDate != null) {
            currentDate.setTime(endDate);
        }
        currentDate.add(GregorianCalendar.DATE, mondayPlus - 8);
        Date monday = currentDate.getTime();

        DateFormat df = DateFormat.getDateInstance();
        String preMonday = df.format(monday);
        return preMonday;
    }

    public static Date getSundayOfLastFourWeekDate(Date endDate) {

        int mondayPlus = 0;
        if (endDate != null) {
            mondayPlus = getMondayDate(endDate);
        } else {
            mondayPlus = getMondayPlus();
        }
        GregorianCalendar currentDate = new GregorianCalendar();
        if (endDate != null) {
            currentDate.setTime(endDate);
        }
        currentDate.add(GregorianCalendar.DATE, mondayPlus - 8);
        Date monday = currentDate.getTime();

        return monday;
    }

    /**
     * 当天开始时间 XX-XX-XX 00:00:00
     */
    public static String beginToday() {

        String dateStr = format(new Date());
        return dateStr + " 00:00:00";
    }

    /**
     * 当天结束时间 XX-XX-XX 23:59:59
     */
    public static String endToday() {

        String dateStr = format(new Date());
        return dateStr + " 23:59:59";
    }


    /**
     * 获取某个日期的当月的最后一天
     *
     * @param date
     * @return
     */
    public static Date getLastDayOfMonth(Date date) {

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        final int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        Date lastDate = cal.getTime();
        lastDate.setDate(lastDay);
        return lastDate;
    }

    /**
     * 获取某个日期的当年的第一天（一月一日）
     *
     * @param date
     * @return
     */
    public static Date getFirstDayOfYear(Date date) {

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int currentYear = cal.get(Calendar.YEAR);
        cal.clear();
        cal.set(Calendar.YEAR, currentYear);
        Date currYearFirst = cal.getTime();
        return currYearFirst;
    }


    /**
     * 两个时间相差距离多少天多少小时多少分多少秒
     *
     * @param beginDate 时间参数 1 格式：1990-01-01 12:00:00
     * @param endDate   时间参数 2 格式：2009-01-01 12:00:00
     * @return String 返回值为：xx天xx小时xx分xx秒
     */
    public static String getDistanceTime(Date beginDate, Date endDate) {

        long day = 0;
        long hour = 0;
        long min = 0;
        long sec = 0;
        try {

            long time1 = beginDate.getTime();
            long time2 = endDate.getTime();
            long diff;
            if (time1 < time2) {
                diff = time2 - time1;
            } else {
                diff = time1 - time2;
            }
            day = diff / (24 * 60 * 60 * 1000);
            hour = (diff / (60 * 60 * 1000) - day * 24);
            min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
            sec = (diff / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

        // hour + "小时" + min + "分" + sec + "秒"
        if (hour == 0) {
            if (min == 0) {
                return sec + "秒";
            } else {
                return min + "分" + sec + "秒";
            }
        } else {
            return hour + "小时" + min + "分" + sec + "秒";
        }
    }

    /**
     * ｛获得指定多少分钟后的时间点｝
     *
     * @author zuo_xz
     * @created 2016-12-12 下午6:16:58
     */
    public static Date getDateByMinute(Date date, int min) {

        Calendar now = Calendar.getInstance();
        now.setTime(date);
        now.add(Calendar.MINUTE, min);
        return now.getTime();
    }

    public static Date getCurrDateByMinute(int min) {

        return getDateByMinute(new Date(), min);
    }

    public static Map<String, String> WeekMap = new HashMap<String, String>();

    static {
        WeekMap.put("星期一", "周一");
        WeekMap.put("星期二", "周二");
        WeekMap.put("星期三", "周三");
        WeekMap.put("星期四", "周四");
        WeekMap.put("星期五", "周五");
        WeekMap.put("星期六", "周六");
        WeekMap.put("星期日", "周日");
    }

    // 得到上个26号
    public static Date getTwentySixDateOfLastMonth() {

        Calendar c = Calendar.getInstance();
        Integer month = c.get(Calendar.MONTH) + 1;
        if (month == 1) {
            c.set(Calendar.MONTH, 12);
            c.set(Calendar.YEAR, c.get(Calendar.YEAR) - 1);
        } else {
            c.set(Calendar.MONTH, c.get(Calendar.MONTH) - 1);
        }
        c.set(Calendar.DAY_OF_MONTH, 26);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    public static boolean isSameYear(Date date1, Date date2) {

        if (date1 == null || date2 == null) {
            return false;
        } else {
            Calendar cal1 = Calendar.getInstance();
            cal1.setTime(date1);
            Calendar cal2 = Calendar.getInstance();
            cal2.setTime(date2);
            return isSameYear(cal1, cal2);
        }
    }

    public static boolean isSameYear(Calendar cal1, Calendar cal2) {

        if (cal1 == null || cal2 == null) {
            return false;
        } else {
            return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR);
        }
    }

    public static String formateDate(Date date) {

        if (date == null) {
            return null;
        }
        SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT_YMD_2);
        return format.format(date);
    }

    /**
     * 当年第一天
     *
     * @param date 日期
     * @return 天
     * @throws Exception 异常
     */
    public static Date getThisYear(String date) throws Exception {

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat format3 = new SimpleDateFormat("yyyy");
        Date time = format3.parse(date);
        String time1 = format3.format(time);
        Date startTime = format.parse(time1 + "-01-01");
        return startTime;
    }

    /**
     * 计算2个日期之间相差的 相差多少年月日 比如：2011-02-02 到 2017-03-02 相差 6年，1个月，0天
     *
     * @param fromDate
     * @param toDate
     * @return
     */
    public static int[] dayComparePrecise(Date fromDate, Date toDate) {

        Calendar from = Calendar.getInstance();
        from.setTime(fromDate);
        Calendar to = Calendar.getInstance();
        to.setTime(toDate);

        int fromYear = from.get(Calendar.YEAR);
        int fromMonth = from.get(Calendar.MONTH);
        int fromDay = from.get(Calendar.DAY_OF_MONTH);

        int toYear = to.get(Calendar.YEAR);
        int toMonth = to.get(Calendar.MONTH);
        int toDay = to.get(Calendar.DAY_OF_MONTH);

        int day = toDay - fromDay;
        if (toMonth < fromMonth) {
            toMonth += 12;
            fromYear += 1;
        }
        Integer year = toYear - fromYear;
        Integer month = toMonth - fromMonth;
        int[] array = {year, month};
        return array;
    }

    public static int getWorkDays(Date startDate, Date endDate) {
        Calendar cl1 = Calendar.getInstance();
        Calendar cl2 = Calendar.getInstance();
        cl1.setTime(startDate);
        cl2.setTime(endDate);
        int count = 0;
        while (cl1.compareTo(cl2) <= 0) {
            if (cl1.get(Calendar.DAY_OF_WEEK) != 7 && cl1.get(Calendar.DAY_OF_WEEK) != 1) {
                count++;
            }
            cl1.add(Calendar.DAY_OF_MONTH, 1);
        }
        return count;
    }

    public static boolean isTheDayInWeek(Integer index) {

        if (index == null) {
            return false;
        }
        Calendar cal = Calendar.getInstance();
        int i = cal.get(Calendar.DAY_OF_WEEK) - 1;
        return i == index;
    }

    public static boolean isTheDayInWeekList(List<Integer> list) {
        for (Integer integer : list) {
            if (isTheDayInWeek(integer)) {
                return true;
            }
        }
        return false;
    }
}
